home *** CD-ROM | disk | FTP | other *** search
- /***********************************************************************\
- * Thread.c *
- * Copyright (C) by Stangl Roman, 1994 *
- * This Code may be freely distributed, provided the Copyright isn't *
- * removed, under the conditions indicated in the documentation. *
- * *
- * Thread.c PC/2's object window working thread. *
- * *
- \***********************************************************************/
-
- static char RCSID[]="@(#) $Header: Thread.c Version 1.70 06,1994 $ (LBL)";
-
- #define _FILE_ "PC/2 - Thread.c V1.70"
-
- #include "PC2.h" /* User include files */
- #include "Error.h"
-
- typedef struct _ColorWindow COLORWINDOW;
-
- struct _ColorWindow
- {
- ULONG ulBackgroundRGB; /* RGB background color of window drawn on overview window */
- ULONG ulForegroundRGB; /* RGB foreground color of window text */
- };
-
- HWND hwndThread; /* PC/2's working thread window handle */
- HPS hpsClient; /* PC/2's client area presentation space */
- SWP swpApplications[128]; /* Window position of all enumerated applications
- except Window List, PC/2 and optionally Desktop */
- ULONG ulApplicationsCount; /* Counter of last filled entry within array
- swpApplications */
-
- /* PC/2's working thread */
- void _Optlink PC2_Thread(void *ThreadArg)
- {
- HAB habThread;
- HMQ hmqThread;
- QMSG qmsgThread;
-
- while(TRUE)
- {
- /* Initialize anchor block and message queue */
- if(WinStartUp(&habThread, &hmqThread)==FALSE)
- {
- USR_ERR("Can't create a object window Thread - exiting...", (HWND)NULL, (HWND)NULL);
- /* On error shut down PC/2 */
- WinPostMsg(hwndClient, WM_QUIT, NULL, NULL);
- break;
- }
- if(!WinRegisterClass( /* Register window class */
- habThread, /* Handle of anchor block */
- (PSZ)PC2_CLASSNAME_THREAD, /* Window class name */
- (PFNWP)PC2_ThreadWindowProc, /* Address of window procedure */
- CS_SIZEREDRAW | CS_SAVEBITS,
- 0)) /* Extra window words */
- {
- GEN_ERR(habThread, (HWND)NULL, (HWND)NULL);
- /* On error shut down PC/2 */
- WinPostMsg(hwndClient, WM_QUIT, NULL, NULL);
- break;
- }
- hwndThread=WinCreateWindow(
- HWND_OBJECT, /* Parent window */
- PC2_CLASSNAME_THREAD, /* Window class */
- NULL, /* Window text */
- 0, /* Window style */
- /* Windos position & size */
- 0, 0, 0, 0,
- HWND_OBJECT, /* Owner window */
- HWND_BOTTOM, /* Sibling window */
- ID_PC2MAINWINDOW, /* Window ID */
- NULL, /* Control data */
- NULL); /* Presentation parameters */
- /* Create a standard window */
- /* *\
- * Now setup working thread's required data. *
- \* */
- /* Get presentation space for PC/2's client window */
- hpsClient=WinGetPS(hwndClient);
- /* Set default font to 8.Helv */
- WinSetPresParam(hwndClient, PP_FONTNAMESIZE, sizeof("8.Helv"), "8.Helv");
- GpiCreateLogColorTable(hpsClient, /* Change color table into RGB mode */
- 0L, /* Options */
- LCOLF_RGB, /* Set color table into RGB mode */
- 0L, 0L, NULL); /* Starting, ending item, table */
- /* Post message to query Desktop's/PM window handle */
- WinPostMsg(hwndThread, WM_SETDESKTOPHANDLE, NULL, NULL);
- /* Start working thread task loop */
- WinPostMsg(hwndThread, WM_WORKINGTHREAD, NULL, NULL);
- /* *\
- * Here we loop dispatching the messages... *
- \* */
- while(WinGetMsg(habThread, &qmsgThread, 0, 0, 0))
- /* Dispatch messages to window procedure */
- WinDispatchMsg(habThread, &qmsgThread);
- break;
- }
- WinReleasePS(hpsClient); /* Release presentation space */
- WinDestroyWindow(hwndThread); /* Close window */
- WinDestroyMsgQueue(hmqThread);
- WinTerminate(habThread);
- _endthread(); /* Terminate C thread code */
- DosExit(EXIT_THREAD, 0UL); /* Terminate thread */
- }
-
- /*--------------------------------------------------------------------------------------*\
- * This procedure is the PC/2 working thread window procedure (is an object window). *
- \*--------------------------------------------------------------------------------------*/
- MRESULT EXPENTRY PC2_ThreadWindowProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
- {
- static ULONG ulRepaintRequest=0; /* Count overview window repaint requests */
-
- switch(msg)
- {
- /* *\
- * Syntax: WM_REPAINT, NULL, NULL *
- \* */
- case WM_REPAINT:
- /* *\
- * This message is send by any function that thinks the overview window needs to be *
- * redrawn. The variable ulRepaintRequest is used to stack repaint request reducing *
- * unnecessary redrawing. *
- * Ref.: *
- * none *
- \* */
- ulRepaintRequest++; /* Register repaint request */
- break;
-
- /* *\
- * Syntax: WM_WORKINGTHREAD, NULL, NULL *
- \* */
- case WM_WORKINGTHREAD:
- /* *\
- * This message is posted from the working thread to itself to permanently do a loop *
- * where pending tasks can be performed. *
- * Ref.: *
- * ulRepaintRequest *
- \* */
- /* Get current windows on PM */
- WinSendMsg(hwnd, WM_SETUPSIZEPOSITION, NULL, NULL);
- /* Test if some window positions have changed or
- must be changed. If necessary move the windows */
- WinSendMsg(hwnd, WM_DESKTOPMOVE, MPFROMLONG(0), MPFROMLONG(0));
- if(ulRepaintRequest) /* If overview window should be redrawn */
- { /* Repaint overview window and reset repaint request counter */
- WinSendMsg(hwnd, WM_PAINT, NULL, NULL);
- ulRepaintRequest=0;
- }
- DosSleep(200); /* Give up some CPU timeslice */
- /* Post message to query Desktop's/PM window handle */
- WinPostMsg(hwnd, WM_SETDESKTOPHANDLE, NULL, NULL);
- /* Do loop to perform pending tasks */
- WinPostMsg(hwnd, WM_WORKINGTHREAD, NULL, NULL);
- break;
-
- /* *\
- * Syntax: WM_PAINT, NULL, NULL *
- \* */
- case WM_PAINT:
- /* *\
- * This message is send by PC/2's client window when a repaint is needed. *
- * Ref.: *
- * none *
- \* */
- {
- RECTL rcClient; /* Rectangle to redraw */
- LONG lX, lY; /* Position (x|y) on client area */
- LONG lXSize, lYSize; /* Length on client area */
- SWP swpWindow; /* Any window to be drawn on overview window */
- ULONG ulWindowIndex; /* Index in Windows.wdWindow[] */
- /* RGB colors available to draw winwdows */
- COLORWINDOW ColorWindow[]={ {RGB_BLACK, RGB_WHITE}, {RGB_BLUE, RGB_WHITE}, {RGB_GREEN, RGB_BLACK},
- {RGB_CYAN, RGB_BLACK}, {RGB_RED, RGB_WHITE}, {RGB_PINK, RGB_WHITE},
- {RGB_YELLOW, RGB_BLACK} };
-
- /* Get the client area size */
- WinQueryWindowPos(hwndClient, &HookParameters.swpPC2Client);
- /* Set background to dialog background */
- WinQueryWindowRect(hwndClient, &rcClient);
- WinFillRect(hpsClient, &rcClient, WinQuerySysColor(HWND_DESKTOP, SYSCLR_DIALOGBACKGROUND, 0L));
- /* Now get scale factor to scale virtual Desktop
- to client area */
- HookParameters.fScaleX=(float)(HookParameters.swpPC2Client.cx-1)/(3*HookParameters.DesktopSize.x);
- HookParameters.fScaleY=(float)(HookParameters.swpPC2Client.cy)/(3*HookParameters.DesktopSize.y);
- /* Get coordinates (0|0) origin */
- HookParameters.ptlOrigin.x=(HookParameters.VirtualDesktopPos.x+HookParameters.DesktopSize.x)*HookParameters.fScaleX;
- HookParameters.ptlOrigin.y=(HookParameters.VirtualDesktopPos.y+HookParameters.DesktopSize.y)*HookParameters.fScaleY;
- /* Get size of one of the 3 Desktops that must fit into
- the client area */
- lXSize=HookParameters.swpPC2Client.cx/3;
- lYSize=HookParameters.swpPC2Client.cy/3;
- swpWindow.cx=lXSize-1;
- swpWindow.cy=lYSize-1;
- for(lX=0; lX<=2; lX++) /* Draw all 9 Virtual Desktops */
- for(lY=0; lY<=2;lY++)
- {
- swpWindow.x=lX*lXSize;
- swpWindow.y=lY*lYSize;
- DrawWindow(hpsClient, &swpWindow, WinQuerySysColor(HWND_DESKTOP, SYSCLR_DIALOGBACKGROUND, 0L),
- 0, FALSE, NULL);
- }
- /* Draw physical Desktop window */
- swpWindow.x=HookParameters.ptlOrigin.x;
- swpWindow.y=HookParameters.ptlOrigin.y;
- DrawWindow(hpsClient, &swpWindow, RGB_WHITE, RGB_BLACK, TRUE, "Display");
- /* Now display the windows from topmost to bottommost */
- for(ulWindowIndex=Windows.ulWindowLast;
- ulWindowIndex!=(ULONG)-1 && Windows.ulWindowLast!=(ULONG)-1;
- ulWindowIndex--)
- {
- /* Ignore invisible windows */
- if(!(Windows.wdWindow[ulWindowIndex].ulStatus & VISIBLE)) continue;
- /* Calculate and draw window */
- swpWindow.x=HookParameters.ptlOrigin.x+
- (float)Windows.wdWindow[ulWindowIndex].swpWindow.x*HookParameters.fScaleX;
- swpWindow.y=HookParameters.ptlOrigin.y+
- (float)Windows.wdWindow[ulWindowIndex].swpWindow.y*HookParameters.fScaleY;
- swpWindow.cx=(float)Windows.wdWindow[ulWindowIndex].swpWindow.cx*HookParameters.fScaleX;
- swpWindow.cy=(float)Windows.wdWindow[ulWindowIndex].swpWindow.cy*HookParameters.fScaleY;
- /* Display Window List title or titlebar */
- if(strlen(Windows.wdWindow[ulWindowIndex].ucWindowTitle))
- DrawWindow(hpsClient, &swpWindow,
- ColorWindow[ulWindowIndex % (sizeof(ColorWindow)/sizeof(COLORWINDOW))].ulBackgroundRGB,
- ColorWindow[ulWindowIndex % (sizeof(ColorWindow)/sizeof(COLORWINDOW))].ulForegroundRGB,
- TRUE, Windows.wdWindow[ulWindowIndex].ucWindowTitle);
- else
- DrawWindow(hpsClient, &swpWindow,
- ColorWindow[ulWindowIndex % (sizeof(ColorWindow)/sizeof(COLORWINDOW))].ulBackgroundRGB,
- ColorWindow[ulWindowIndex % (sizeof(ColorWindow)/sizeof(COLORWINDOW))].ulForegroundRGB,
- TRUE, Windows.wdWindow[ulWindowIndex].ucPgmTitle);
- }
- }
- break;
-
- /* *\
- * Syntax: WM_DESKTOPMOVE, LONG SlidingXFactor, LONG SlidingYFactor *
- \* */
- case WM_DESKTOPMOVE:
- /* *\
- * The hook found that the pointer was over one of the border rows and/or columns of *
- * the physical Desktop or the user doubleclicked on a virtual Desktop on the overview *
- * window. The passed parameter mp1 contains the number of pixels to slide all windows *
- * on the virtual Desktop horizontally. We calculate if and where the physical Desktop *
- * must be moved, or ignore it, if we're allready at a border position of the virtual *
- * Desktop. *
- \* */
- {
- /* Slide in x direction in pixels */
- LONG lSlidingXFactor=LONGFROMMP(mp1);
- /* Slide in y direction in pixels */
- LONG lSlidingYFactor=LONGFROMMP(mp2);
- ULONG ulWindowIndex=0; /* Index in WINDOWS structure */
- BOOL bChanged=FALSE; /* TRUE is at least one window has been changed
- (added, removed, moved, sized,...) */
-
- ulApplicationsCount=0; /* Begin with first window */
- /* From all windows select the ones we are
- interested to move */
- for( ; ulWindowIndex<=Windows.ulWindowLast; ulWindowIndex++)
- {
- /* Ignore known windows not being a movable frame window. */
- if(!(Windows.wdWindow[ulWindowIndex].ulStatus & FRAMECLASS))
- continue;
- /* Preserve Window list */
- if(!strcmp(Windows.wdWindow[ulWindowIndex].ucPgmTitle, HookParameters.ucWindowListName))
- continue;
- /* Preserve PC/2's window */
- if((strstr(Windows.wdWindow[ulWindowIndex].ucWindowTitle, "PC/2")) ||
- (strstr(Windows.wdWindow[ulWindowIndex].ucPgmTitle, "PC/2"))) continue;
- /* Only move certain window */
- Windows.wdWindow[ulWindowIndex].swpWindow.x+=lSlidingXFactor;
- Windows.wdWindow[ulWindowIndex].swpWindow.y+=lSlidingYFactor;
- /* Copy flags to prevent unnecessary update only because
- some styles mismatch we can ignore safely */
- swpApplications[ulApplicationsCount].fl=Windows.wdWindow[ulWindowIndex].swpWindow.fl;
- /* Now compare current one if it changed */
- if(memcmp(&swpApplications[ulApplicationsCount], &Windows.wdWindow[ulWindowIndex].swpWindow, sizeof(SWP)))
- {
- bChanged=TRUE;
- memcpy(&swpApplications[ulApplicationsCount], &Windows.wdWindow[ulWindowIndex].swpWindow, sizeof(SWP));
- /* Move window only if not marked non-movable. Such a window
- appears on every Virtual Desktop but may change its position
- relative to the lower left corner so we have to compare its
- old and new position to update overview window correctly */
- if(Windows.wdWindow[ulWindowIndex].SwpFlag & SWP_NOMOVE)
- swpApplications[ulApplicationsCount].fl=SWP_NOADJUST;
- else
- swpApplications[ulApplicationsCount].fl=SWP_MOVE | SWP_NOADJUST;
- }
- ulApplicationsCount++;
- }
- /* Now move all windows */
- if(lSlidingXFactor || lSlidingYFactor)
- {
- if(WinSetMultWindowPos(hab, swpApplications, ulApplicationsCount))
- {
- bChanged=TRUE; /* If windows were successfully moved update overview window */
- /* Adjust physical Desktop within virtual Desktop */
- HookParameters.VirtualDesktopPos.x-=lSlidingXFactor;
- HookParameters.VirtualDesktopPos.y-=lSlidingYFactor;
- }
- else
- /* If windows weren't successfully moved retry */
- WinPostMsg(hwnd, WM_DESKTOPMOVE, MPFROMLONG(lSlidingXFactor), MPFROMLONG(lSlidingYFactor));
-
- }
- /* If windows changed, request repaint client area */
- if(bChanged) WinPostMsg(hwnd, WM_REPAINT, NULL, NULL);
- }
- break;
-
- /* *\
- * Syntax: WM_SETDESKTOPHANDLE, NULL, NULL *
- \* */
- case WM_SETDESKTOPHANDLE:
- /* *\
- * Query the window handle of the Desktop windows and load them into PC2HOOK.DLL *
- * library. If the WPS is installed, we can obtain its handle by searching for a window *
- * class of #37. Even if the WPS is installed, we can also obtain the the window handle *
- * of the PM, which is also present, if the WPS isn't installed. *
- * Ref.: *
- * Windows ........... WINDOWS structure containing all windows control data *
- \* */
- {
- UCHAR ucClass[8]; /* Save class name here */
- HWND hwndWPS; /* Save WPS window handle */
- HWND hwndDesktop; /* Save PM window handle */
- HENUM henumWindows; /* Enumerate windows */
-
- /* Get to bottommost window handle of the "Desktop" */
- hwndDesktop=WinQueryWindow(HWND_DESKTOP, QW_BOTTOM);
- /* Enumerate all windows at "Desktop" z-order */
- henumWindows=WinBeginEnumWindows(hwndDesktop);
- while(hwndWPS=WinGetNextWindow(henumWindows))
- {
- /* Now get the class name of that window handle */
- WinQueryClassName(hwndWPS, sizeof(ucClass), (PCH)ucClass);
- /* If we find the required "Desktop" window (it
- has a class name of #37, which is reserved in the
- Toolkit) set this value into the Hook DLL.
- The "Desktop" is just a WC_CONTAINER class.
- This class is owned by the WPS, so we found the
- WPS' window handle */
- if(!strcmp(ucClass, DESKTOP_CLASS)) break;
- }
- WinEndEnumWindows(henumWindows); /* End enumeration */
- /* *\
- * Now get the PM window handle for the case, that the WPS is not installed, or moved *
- * outwards of the display (by setting the move Desktop checkbox). *
- \* */
- /* Without WPS installed we can only get the
- "Desktop" window handle */
- hwndDesktop=WinQueryDesktopWindow(hab, NULLHANDLE);
- /* Inform DLL if Desktop windows handles have
- changed */
- if((hwndWPS!=HookParameters.hwndWPS) || (hwndDesktop!=HookParameters.hwndDesktop))
- {
- HookParameters.hwndWPS=hwndWPS;
- HookParameters.hwndDesktop=hwndDesktop;
- }
- }
- break;
-
- /* *\
- * Syntax: WM_SETUPSIZEPOSITION, NULL, NULL *
- \* */
- case WM_SETUPSIZEPOSITION:
- /* *\
- * This message is executed in a loop by the object window thread. At the end of this *
- * message the message is posted again, after sleeping a while, to perform the loop. *
- * All windows running in the system are queried and registered in the Windows control *
- * structure. *
- * The Window List is queried to find the Window List entries of the PM windows. *
- * Ref.: *
- * Windows ........... WINDOWS structure containing all windows control data *
- \* */
- {
- ULONG ulWindowIndex; /* Index in Windows.wdWindow[] */
- HENUM henumDesktop; /* Window handle of WC_FRAME class Desktop */
- HWND hwndApplication; /* Window handles of enumerated application */
- ULONG ulWindowListCount, ulWindowListIndex;
- MENUDATA *pMD; /* Pointer to MENUDATA structure of corresponding window */
- PSWBLOCK pSwBlock; /* Pointer to window list */
- BOOL bFoundItem; /* TRUE if hotkey was found */
-
- /* Query the number of entries in window list */
- ulWindowListCount=WinQuerySwitchList(hab, NULL, 0);
- /* Allocate space for window list */
- pSwBlock=(PSWBLOCK)malloc(ulWindowListCount=(ulWindowListCount*sizeof(SWENTRY)+sizeof(HSWITCH)));
- /* Enumerate window list to query how the Session title of a
- frame window (using it's window handle) is spelled in the
- Window list */
- ulWindowListCount=WinQuerySwitchList(hab, pSwBlock, ulWindowListCount);
- Windows.ulDesktop=(ULONG)-1; /* Set to -1 if we don't find the Desktop's name */
- Windows.ulWindowList=(ULONG)-1; /* Set to -1 if we don't find the Window List's name */
- ulWindowIndex=(ULONG)-1; /* Begin with offset 0 in first iteration */
- /* Enumerate all descendants of HWND_DESKTOP,
- which are the frame windows seen on Desktop,
- but not having necessarily the class WC_FRAME */
- henumDesktop=WinBeginEnumWindows(HWND_DESKTOP);
- while(hwndApplication=WinGetNextWindow(henumDesktop))
- {
- ulWindowIndex++;
- /* Asume window visible */
- Windows.wdWindow[ulWindowIndex].ulStatus|=VISIBLE;
- Windows.wdWindow[ulWindowIndex].ulStatus|=FRAMECLASS;
- /* Get window's size and position */
- WinQueryWindowPos(hwndApplication, &Windows.wdWindow[ulWindowIndex].swpWindow);
- if(Windows.wdWindow[ulWindowIndex].swpWindow.fl & SWP_HIDE)
- Windows.wdWindow[ulWindowIndex].ulStatus &= (~VISIBLE);
- /* Get window's class name */
- WinQueryClassName(hwndApplication, CLASSNAMESIZE,
- Windows.wdWindow[ulWindowIndex].ucClassName);
- /* If it is an minimized icon text class window
- treat it as an invisible one */
- if(!strcmp(Windows.wdWindow[ulWindowIndex].ucClassName, "#32765"))
- Windows.wdWindow[ulWindowIndex].ulStatus &= (~VISIBLE);
- /* If it is a menu treat it as an invisible one and
- not being a frame window */
- if(!strcmp(Windows.wdWindow[ulWindowIndex].ucClassName, "#4"))
- {
- Windows.wdWindow[ulWindowIndex].ulStatus &= (~VISIBLE);
- Windows.wdWindow[ulWindowIndex].ulStatus &= (~FRAMECLASS);
- }
- /* Get window's titlebar */
- WinQueryWindowText(hwndApplication, MAXNAMEL+1,
- Windows.wdWindow[ulWindowIndex].ucPgmTitle);
- /* If we found the index of the Window List save it */
- if(strstr(Windows.wdWindow[ulWindowIndex].ucPgmTitle, HookParameters.ucWindowListName))
- {
- Windows.ulWindowList=ulWindowIndex;
- Windows.wdWindow[ulWindowIndex].ulStatus &= (~FRAMECLASS);
- }
- /* If we found the index of the Desktop save it */
- if(strstr(Windows.wdWindow[ulWindowIndex].ucPgmTitle, HookParameters.ucDesktopName))
- {
- Windows.ulDesktop=ulWindowIndex;
- if(!(HookParameters.ulStatusFlag & MOVEDESKTOP))
- Windows.wdWindow[ulWindowIndex].ulStatus &= (~FRAMECLASS);
- }
- /* If we found PC/2, or any of PC/2's dialogs save it */
- if(hwndApplication==hwndFrame)
- {
- Windows.wdWindow[ulWindowIndex].ulStatus &= (~VISIBLE);
- /* Keep overview window on top (the focus may be in a
- window below */
- if(HookParameters.ulStatusFlag & KEEPONTOP)
- WinSetWindowPos(hwndFrame, HWND_TOP, 0, 0, 0, 0, SWP_ZORDER);
- }
- if(strstr(Windows.wdWindow[ulWindowIndex].ucPgmTitle, "PC/2"))
- Windows.wdWindow[ulWindowIndex].ulStatus &= (~VISIBLE);
- /* If we don't find an entry in the Window List set
- it to default empty string */
- strcpy(Windows.wdWindow[ulWindowIndex].ucWindowTitle, "");
- /* If we don't find an entry set to 0 */
- Windows.wdWindow[ulWindowIndex].hswitchWindow=0;
- for(ulWindowListIndex=0; ulWindowListIndex<=ulWindowListCount; ulWindowListIndex++)
- { /* If window handle of frame window and window handle in
- window list equal, copy the name of the entry from the
- window list */
- if(pSwBlock->aswentry[ulWindowListIndex].swctl.hwnd==Windows.wdWindow[ulWindowIndex].swpWindow.hwnd)
- {
- strcpy(Windows.wdWindow[ulWindowIndex].ucWindowTitle,
- pSwBlock->aswentry[ulWindowListIndex].swctl.szSwtitle);
- /* Get the switch handle */
- Windows.wdWindow[ulWindowIndex].hswitchWindow=pSwBlock->aswentry[ulWindowListIndex].hswitch;
- break; /* If found we need no further seek */
- }
- }
- /* Search if current window is contained in PC/2's
- Popup-Menu */
- bFoundItem=FALSE;
- pMD=SearchTitle(pPopupMenu, &Windows.wdWindow[ulWindowIndex], &bFoundItem);
- if(pMD!=NULL)
- /* If found copy flag because we need to determine
- if window should be moved on virtual Desktops
- and how it should be restored when hotkeying to it */
- {
- Windows.wdWindow[ulWindowIndex].SwpFlag=pMD->SwpFlag;
- memcpy(&Windows.wdWindow[ulWindowIndex].KeyData, &(pMD->KeyData), sizeof(KEYDATA));
- if(pMD->SwpFlag & SWP_MOVEWINDOW)
- {
- USHORT usSwp;
- /* If window was only invisible because of the movement
- make it visible again */
- if(pMD->SwpFlag & SWP_MOVEWINDOWVISIBLE)
- usSwp=SWP_MOVE | SWP_SHOW | SWP_NOADJUST;
- else
- usSwp=SWP_MOVE | SWP_NOADJUST;
- /* If this flag is set we found an application's window
- the first time after invokation and we have to reposition
- it and reset the flag */
- pMD->SwpFlag&=(~(SWP_MOVEWINDOW | SWP_MOVEWINDOWVISIBLE));
- /* Now calculate window's position on Virtual Desktops and
- move it to its absolute (relative to logical 0|0) position */
- WinSetWindowPos(Windows.wdWindow[ulWindowIndex].swpWindow.hwnd, HWND_TOP,
- pMD->InitXPos-HookParameters.VirtualDesktopPos.x,
- pMD->InitYPos-HookParameters.VirtualDesktopPos.y,
- 0, 0, usSwp);
- }
- }
- else
- {
- Windows.wdWindow[ulWindowIndex].SwpFlag=0;
- memset(&Windows.wdWindow[ulWindowIndex].KeyData, 0, sizeof(KEYDATA));
- }
- }
- WinEndEnumWindows(henumDesktop); /* End enumeration */
- Windows.ulWindowLast=ulWindowIndex;
- free(pSwBlock);
- }
- break;
-
- /* *\
- * Syntax: WM_BUTTON1DBLCLK, (LONG mp1), (LONG mp2) *
- \* */
- case WM_BUTTON1DBLCLK:
- /* *\
- * This message detected and passed from the PC/2 window procedure is used to switch *
- * between Virtual Desktops. *
- * Ref.: *
- * Windows ........... WINDOWS structure containing all windows control data *
- \* */
- {
- LONG lClickX, lClickY; /* Pointer position during click */
- LONG lSlidingXFactor; /* Slide in x direction in pixels */
- LONG lSlidingYFactor; /* Slide in y direction in pixels */
-
- /* Get the virtual Desktop the user doubleclicked on */
- lClickX=-HookParameters.DesktopSize.x;
- lClickY=-HookParameters.DesktopSize.y;
- lClickX+=((LONG)(SHORT1FROMMP(mp1)))/(HookParameters.swpPC2Client.cx/3)*HookParameters.DesktopSize.x;
- lClickY+=((LONG)(SHORT2FROMMP(mp1)))/(HookParameters.swpPC2Client.cy/3)*HookParameters.DesktopSize.y;
- /* The right and top borders are the limit (necessary because
- the frame rectrangle is sized pointwise and the virtual Desktops
- drawn are sized every 3 points leaving 0 to 2 points outside.
- Can be fixed by allowing the frame also sized only every 3
- points, but I first must find out how to. */
- if(lClickX>HookParameters.VirtualDesktopMax.x) lClickX=HookParameters.VirtualDesktopMax.x;
- if(lClickY>HookParameters.VirtualDesktopMax.y) lClickY=HookParameters.VirtualDesktopMax.y;
- /* Calculate Desktop move in pixel */
- lSlidingXFactor=HookParameters.VirtualDesktopPos.x-lClickX;
- lSlidingYFactor=HookParameters.VirtualDesktopPos.y-lClickY;
- if(lSlidingXFactor || lSlidingYFactor)
- /* Now move the windows */
- WinPostMsg(hwndThread, WM_DESKTOPMOVE, MPFROMLONG(lSlidingXFactor), MPFROMLONG(lSlidingYFactor));
- }
- break;
-
- /* *\
- * Syntax: WM_HOTKEY, (USHORT usFlags, USHORT usCh), ULONG ulKeyDataIndex *
- * *
- \* */
- case WM_HOTKEY:
- /* *\
- * WM_HOTKEY is a WM_CHAR message, passed when a hotkey was detected in PC2Hook.DLL. *
- * The key passed from the input hook is flaged as used. Either the running program *
- * corresponding to the hotkey is switched into the foreground, or if it is not already *
- * running it is started. *
- * Ref.: *
- * Windows ........... WINDOWS structure containing all windows control data *
- \* */
- {
- /* Get key code */
- USHORT usFlags=SHORT1FROMMP(mp1);
- /* Get ASCII key value */
- USHORT usCh=SHORT2FROMMP(mp1);
- /* Index in KeyData of HotKey found */
- ULONG ulKeyDataIndex=LONGFROMMP(mp2);
- POINTL VirtualDesktopPos; /* Copy structure from HookParameters */
- ULONG ulWindowIndex; /* Index in Windows.wdWindow[] */
- POINTL HotKeyWindow; /* Position of the window the Hotkey is defined for
- in coordinates relative to logical (0|0) point */
- LONG lSlidingXFactor=0; /* Slide in x direction in pixels */
- LONG lSlidingYFactor=0; /* Slide in y direction in pixels */
- LONG lDiff;
- USHORT usfl; /* Flags for WinSetWindowPos() */
-
- VirtualDesktopPos=HookParameters.VirtualDesktopPos;
- /* Find match between actual hotkey pressed and
- any (available) window this hotkey is defined for */
- for(ulWindowIndex=0; ulWindowIndex<=Windows.ulWindowLast; ulWindowIndex++)
- {
- if((Windows.wdWindow[ulWindowIndex].KeyData.usFlags==usFlags) &&
- (Windows.wdWindow[ulWindowIndex].KeyData.usCh==usCh))
- break;
- }
- /* Only do something when a window for a hotkey
- is available */
- if(ulWindowIndex<=Windows.ulWindowLast)
- { /* The coordinates in the WINDOWS structure are relative to
- PM, which is, if the Virtual Desktop is enabled, relative
- to the logical (0|0) point (which is the lower left position
- of the Display in the overview window.
- To get the position relative to logical (0|0) get the winow's
- position on PM and add the logical position of PM relative to
- logical (0|0). Compare with the middle of the hotkeyed window. */
- HotKeyWindow.x=HookParameters.VirtualDesktopPos.x+
- Windows.wdWindow[ulWindowIndex].swpWindow.x+(Windows.wdWindow[ulWindowIndex].swpWindow.cx>>1);
- HotKeyWindow.y=HookParameters.VirtualDesktopPos.y+
- Windows.wdWindow[ulWindowIndex].swpWindow.y+(Windows.wdWindow[ulWindowIndex].swpWindow.cy>>1);
- /* Move physical Desktop right, but not over the
- right border of the virtual Desktop until
- the hotkeyed window's horizontal position comes
- onto the Desktop */
- while(HotKeyWindow.x>(VirtualDesktopPos.x+HookParameters.SlidingXFactor))
- { /* Move physical Desktop right one additional unit,
- can also be seen to move all windows in virtual
- Desktop left one additional unit */
- lSlidingXFactor-=HookParameters.SlidingXFactor;
- VirtualDesktopPos.x+=HookParameters.SlidingXFactor;
- lDiff=VirtualDesktopPos.x-HookParameters.VirtualDesktopMax.x;
- if(lDiff>0) /* Correct if we moved out of the physical Desktop */
- {
- lSlidingXFactor+=lDiff;
- break; /* We can't move further */
- }
- }
- /* Do the same left */
- while(HotKeyWindow.x<VirtualDesktopPos.x)
- { /* Move physical Desktop left one additional unit */
- lSlidingXFactor+=HookParameters.SlidingXFactor;
- VirtualDesktopPos.x-=HookParameters.SlidingXFactor;
- lDiff=VirtualDesktopPos.x-HookParameters.VirtualDesktopMin.x;
- if(lDiff<0) /* Correct if we moved out of the physical Desktop */
- {
- lSlidingXFactor+=lDiff;
- break; /* We can't move further */
- }
- }
- /* Move physical Desktop up, but not over the
- top border of the virtual Desktop until
- the hotkeyed window's vertiacal position comes
- onto the Desktop */
- while(HotKeyWindow.y>(VirtualDesktopPos.y+HookParameters.SlidingYFactor))
- { /* Move physical Desktop up one additional unit,
- can also be seen to move all windows in virtual
- Desktop down one additional unit */
- lSlidingYFactor-=HookParameters.SlidingYFactor;
- VirtualDesktopPos.y+=HookParameters.SlidingYFactor;
- lDiff=VirtualDesktopPos.y-HookParameters.VirtualDesktopMax.y;
- if(lDiff>0) /* Correct if we moved out of the physical Desktop */
- {
- lSlidingYFactor+=lDiff;
- break; /* We can't move further */
- }
- }
- /* Do the same downwards */
- while(HotKeyWindow.y<VirtualDesktopPos.y)
- { /* Move physical Desktop down one additional unit */
- lSlidingYFactor+=HookParameters.SlidingYFactor;
- VirtualDesktopPos.y-=HookParameters.SlidingYFactor;
- lDiff=VirtualDesktopPos.y-HookParameters.VirtualDesktopMin.y;
- if(lDiff<0) /* Correct if we moved out of the physical Desktop */
- {
- lSlidingYFactor+=lDiff;
- break; /* We can't move further */
- }
- }
- if(lSlidingXFactor || lSlidingYFactor)
- /* Now move the windows and activate window after move */
- WinSendMsg(hwndThread, WM_DESKTOPMOVE, MPFROMLONG(lSlidingXFactor), MPFROMLONG(lSlidingYFactor));
- /* Get flags WinSetWindowPos() */
- usfl=(Windows.wdWindow[ulWindowIndex].SwpFlag & ~SWP_NOMOVE) | SWP_SHOW;
- /* If not switch handle found activate window through
- WinSetWindowPos() else via WinSwitchToProgram which
- also switches to different screen groups */
- if(!Windows.wdWindow[ulWindowIndex].hswitchWindow)
- usfl|=(SWP_ACTIVATE | SWP_ZORDER);
- WinSetWindowPos(Windows.wdWindow[ulWindowIndex].swpWindow.hwnd,
- HWND_TOP, 0, 0, 0, 0, usfl);
- if(Windows.wdWindow[ulWindowIndex].hswitchWindow)
- WinSwitchToProgram(Windows.wdWindow[ulWindowIndex].hswitchWindow);
- }
- else
- { /* If no session found for the pressed hotkey, start
- the corresponding session */
- WinPostMsg(hwndClient, WM_COMMAND,
- /* Get ID and set it as posted by a menu control */
- MPFROM2SHORT((USHORT)(KeyData[ulKeyDataIndex].pMenuData->id), CMDSRC_MENU),
- /* Simulate Message a result of a keyboard operation */
- MPFROMCHAR(FALSE));
- }
- }
- break;
-
- /* *\
- * Syntax: WM_WINDOWLIST, (USHORT x, USHORT y), NULL *
- \* */
- case WM_WINDOWLIST:
- /* *\
- * WM_WINDIWLIST is sent by PC2Hook.dll and passed from PC/2's window procedure, if *
- * mouse clicks are detected on PM that would display the Window List on the WPS. Be- *
- * cause the WPS displayed the Window List but not PM, we simulate this on PM. *
- * Ref.: *
- * Windows ........... WINDOWS structure containing all windows control data *
- \* */
- { /* Mouse position when Window List was requested */
- USHORT usX=SHORT1FROMMP(mp1), usY=SHORT2FROMMP(mp1);
-
- if(Windows.ulWindowList!=(ULONG)-1) /* Display Window List */
- {
- /* Place Window List centered under mouse pointer
- whenever possible */
- if((Windows.wdWindow[Windows.ulWindowList].swpWindow.cx>>1)>usX)
- usX=0;
- else if(HookParameters.DesktopSize.x-(Windows.wdWindow[Windows.ulWindowList].swpWindow.cx>>1)<usX)
- usX=HookParameters.DesktopSize.x-Windows.wdWindow[Windows.ulWindowList].swpWindow.cx;
- else usX=usX-(Windows.wdWindow[Windows.ulWindowList].swpWindow.cx>>1);
- if((Windows.wdWindow[Windows.ulWindowList].swpWindow.cy>>1)>usY)
- usY=0;
- else if(HookParameters.DesktopSize.y-(Windows.wdWindow[Windows.ulWindowList].swpWindow.cy>>1)<usY)
- usY=HookParameters.DesktopSize.y-Windows.wdWindow[Windows.ulWindowList].swpWindow.cy;
- else usY=usY-(Windows.wdWindow[Windows.ulWindowList].swpWindow.cy>>1);
- WinSetWindowPos(Windows.wdWindow[Windows.ulWindowList].swpWindow.hwnd,
- HWND_TOP, usX, usY, 0, 0,
- SWP_ZORDER | SWP_MOVE | SWP_SHOW | SWP_ACTIVATE | SWP_NOADJUST);
- }
- }
- break;
-
- /* *\
- * Syntax: WM_MOVEREQUEST, (USHORT usMouseXPos, USHORT usMouseYPos), (ULONG ulMoveFlag) *
- \* */
- case WM_MOVEREQUEST:
- /* *\
- * This local procedure is called from the PC2DLL_Hook procedure to move the windows *
- * within the virtual Desktop on its behalf. *
- * Req: *
- * usMouseXPos.... X Position of mouse pointer during creation of move message *
- * usMouseYPos.... Y Position of mouse pointer during creation of move message *
- * ulMoveFlag..... Bitmapped flag to control move *
- * Returns: *
- * none *
- * Ref.: *
- * Windows ........... WINDOWS structure containing all windows control data *
- \* */
- {
- /* Get pointer position */
- LONG lMouseXPos=(LONG)SHORT1FROMMP(mp1);
- LONG lMouseYPos=(LONG)SHORT2FROMMP(mp1);
- POINTL VirtualDesktopPos; /* Copy structure from HookParameters */
- /* Get bitmapped move control flag */
- ULONG ulMoveFlag=LONGFROMMP(mp2);
- LONG lSlidingXFactor; /* Horizontal offset to move */
- LONG lSlidingYFactor; /* Vertical offset to move */
- LONG lDiff; /* Difference between movement and Desktop size */
-
- lSlidingXFactor=0;
- lSlidingYFactor=0;
- VirtualDesktopPos=HookParameters.VirtualDesktopPos;
- if((ulMoveFlag&MOVEXR))
- { /* Move physical Desktop left, but not over the
- left border of the virtual Desktop */
- lSlidingXFactor=HookParameters.SlidingXFactor;
- VirtualDesktopPos.x-=HookParameters.SlidingXFactor;
- lDiff=VirtualDesktopPos.x-HookParameters.VirtualDesktopMin.x;
- if(lDiff<0)
- {
- lSlidingXFactor+=lDiff;
- }
- }
- if((ulMoveFlag&MOVEXL))
- { /* Move physical Desktop right, but not over the
- right border of the virtual Desktop */
- lSlidingXFactor=-HookParameters.SlidingXFactor;
- VirtualDesktopPos.x+=HookParameters.SlidingXFactor;
- lDiff=VirtualDesktopPos.x-HookParameters.VirtualDesktopMax.x;
- if(lDiff>0)
- {
- lSlidingXFactor+=lDiff;
- }
- }
- if((ulMoveFlag&MOVEYU))
- { /* Move physical Desktop down, but not under the
- bottom border of the virtual Desktop */
- lSlidingYFactor=HookParameters.SlidingYFactor;
- VirtualDesktopPos.y-=HookParameters.SlidingYFactor;
- lDiff=VirtualDesktopPos.y-HookParameters.VirtualDesktopMin.y;
- if(lDiff<0)
- {
- lSlidingYFactor+=lDiff;
- }
- }
- if((ulMoveFlag&MOVEYD))
- { /* Move physical Desktop up, but not over the
- top border of the virtual Desktop */
- lSlidingYFactor=-HookParameters.SlidingYFactor;
- VirtualDesktopPos.y+=HookParameters.SlidingYFactor;
- lDiff=VirtualDesktopPos.y-HookParameters.VirtualDesktopMax.y;
- if(lDiff>0)
- {
- lSlidingYFactor+=lDiff;
- }
- }
- /* If there is nothing to move, because we are
- on a border position, don't do further processing
- but return */
- if(!lSlidingXFactor && !lSlidingYFactor) break;
- /* Move pointer so that it is on that pixel it
- would be, if we hadn't moved the windows. Also
- change the pixel which gets the message. */
- if(HookParameters.ulScrollPercentage==100)
- WinSetPointerPos(HWND_DESKTOP, (lMouseXPos+=lSlidingXFactor*0.5),
- (lMouseYPos+=lSlidingYFactor*0.5));
- else
- WinSetPointerPos(HWND_DESKTOP, (lMouseXPos+=lSlidingXFactor),
- (lMouseYPos+=lSlidingYFactor));
- /* Inform working thread to move windows */
- WinPostMsg(HookParameters.hwndPC2, WM_DESKTOPMOVE,
- MPFROMLONG(lSlidingXFactor), MPFROMLONG(lSlidingYFactor));
- }
- break;
-
- default: /* Default window procedure must be called */
- return((MRESULT)WinDefWindowProc(hwnd, msg, mp1, mp2));
- }
- return((MRESULT)FALSE); /* We have handled the message */
- }
-